#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
实时车牌识别系统 - 主程序入口
"""

import sys
import os
import signal
import traceback
import threading
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))

# GUI相关导入
from PySide6.QtWidgets import QApplication, QMessageBox
from PySide6.QtCore import Qt, QTimer
from PySide6.QtGui import QIcon

# 项目模块导入
from src.gui.main_window import MainWindow
from src.utils.config import Config
from src.utils.logger import Logger
from src.core.processor import PlateProcessor


class Application:
    """
    应用程序主类
    
    功能：
    - 管理应用程序生命周期
    - 处理信号和异常
    - 初始化各个组件
    - 监听控制台退出命令
    """
    
    def __init__(self):
        """初始化应用程序"""
        self.app = None
        self.main_window = None
        self.processor = None
        self.logger = None
        self.config = None
        self.console_thread = None
        self.running = True
        
    def setup_console_listener(self):
        """设置控制台命令监听器"""
        def console_listener():
            """监听控制台输入的线程函数"""
            print("💡 提示：在控制台中输入 'exit'、'quit'、'q' 等命令也可以退出程序")
            print()
            
            while self.running:
                try:
                    # 简化的输入处理，适用于所有平台
                    import time
                    time.sleep(0.5)  # 减少CPU占用
                    
                    # 尝试非阻塞读取
                    try:
                        if sys.platform == "win32":
                            import msvcrt
                            if msvcrt.kbhit():
                                # 简单读取一行
                                line = input().strip().lower()
                                if line in ['exit', 'quit', 'q', 'bye', 'close', 'stop', 'end']:
                                    print(f"✅ 收到退出命令: '{line}'")
                                    self.cleanup_and_exit()
                                    break
                                elif line:
                                    print(f"❓ 未知命令: '{line}'，请输入 'exit' 或 'q' 退出")
                        else:
                            # Unix/Linux平台
                            import select
                            if select.select([sys.stdin], [], [], 0.1)[0]:
                                line = input().strip().lower()
                                if line in ['exit', 'quit', 'q', 'bye', 'close', 'stop', 'end']:
                                    print(f"✅ 收到退出命令: '{line}'")
                                    self.cleanup_and_exit()
                                    break
                                elif line:
                                    print(f"❓ 未知命令: '{line}'，请输入 'exit' 或 'q' 退出")
                    except EOFError:
                        # 输入流关闭
                        break
                    except:
                        # 忽略其他输入错误
                        pass
                        
                except Exception:
                    # 忽略所有异常，继续监听
                    import time
                    time.sleep(0.5)
        
        # 启动控制台监听线程
        self.console_thread = threading.Thread(target=console_listener, daemon=True)
        self.console_thread.start()
        
    def setup_signal_handlers(self):
        """设置信号处理器，支持Ctrl+C中断"""
        def signal_handler(signum, frame):
            print(f"\n收到信号 {signum}，正在关闭程序...")
            self.cleanup_and_exit()
        
        # 注册信号处理器
        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)
        
        # 在Windows上，还需要处理CTRL_C_EVENT
        if sys.platform == "win32":
            try:
                import win32api
                win32api.SetConsoleCtrlHandler(lambda x: self.cleanup_and_exit(), True)
            except ImportError:
                pass  # win32api不可用时跳过
    
    def setup_qt_interrupt_handling(self):
        """设置Qt应用程序的中断处理"""
        # 创建定时器来检查Python信号
        self.timer = QTimer()
        self.timer.timeout.connect(lambda: None)  # 空操作，只是为了让Python有机会处理信号
        self.timer.start(500)  # 每500ms检查一次
        
    def cleanup_and_exit(self):
        """清理资源并退出"""
        if not self.running:
            return  # 避免重复调用
            
        self.running = False
        
        try:
            if self.logger:
                self.logger.info("正在关闭程序...")
            
            # 停止处理器
            if self.processor:
                self.processor.stop()
                
            # 关闭主窗口
            if self.main_window:
                self.main_window.close()
                
            # 退出应用程序
            if self.app:
                self.app.quit()
                
        except Exception as e:
            print(f"清理过程中出错: {e}")
        finally:
            sys.exit(0)
    
    def run(self):
        """运行应用程序"""
        try:
            # 设置信号处理
            self.setup_signal_handlers()
            
            # 启动控制台命令监听
            self.setup_console_listener()
            
            # 初始化Qt应用程序
            self.app = QApplication(sys.argv)
            
            # 设置应用程序属性
            self.app.setApplicationName("实时车牌识别系统")
            self.app.setApplicationVersion("1.0.0")
            self.app.setOrganizationName("车牌识别项目")
            
            # 设置高DPI支持
            if hasattr(Qt, 'AA_EnableHighDpiScaling'):
                QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
            if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
                QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
            
            # 设置Qt中断处理
            self.setup_qt_interrupt_handling()
            
            # 初始化配置
            self.config = Config()
            
            # 初始化日志
            self.logger = Logger(self.config.get('system.log_level', 'INFO'))
            self.logger.info("开始启动应用程序...")
            
            # 初始化处理器
            self.logger.info("开始加载模型...")
            self.processor = PlateProcessor(self.config.get_all())
            self.logger.info("模型加载完成")
            
            # 创建主窗口
            self.main_window = MainWindow()
            
            # 设置窗口图标（如果存在）
            icon_path = project_root / "assets" / "icon.ico"
            if icon_path.exists():
                self.app.setWindowIcon(QIcon(str(icon_path)))
            
            # 显示主窗口
            self.main_window.show()
            
            self.logger.info("应用程序启动成功")
            
            # 运行事件循环
            return self.app.exec()
            
        except KeyboardInterrupt:
            print("\n用户中断程序")
            self.cleanup_and_exit()
        except Exception as e:
            error_msg = f"程序启动失败: {str(e)}"
            print(error_msg)
            print(traceback.format_exc())
            
            if self.logger:
                self.logger.error(error_msg)
            
            # 显示错误对话框
            if hasattr(self, 'app') and self.app:
                QMessageBox.critical(None, "启动错误", error_msg)
            
            return 1


def main():
    """主函数入口"""
    print("=" * 60)
    print("    🚗 实时车牌识别系统 v1.0.0")
    print("=" * 60)
    print("📌 退出程序的方式：")
    print("   1️⃣  按 Ctrl+C")
    print("   2️⃣  输入命令：exit, quit, q, bye, close, stop, end")
    print("   3️⃣  关闭GUI窗口")
    print("-" * 60)
    print("🚀 正在启动程序...")
    print()
    
    app = Application()
    return app.run()


if __name__ == "__main__":
    sys.exit(main()) 